package com.lollipop.synthential.sundry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author: J.K
 * @Date: 2021-02-01 09:12
 * @Description: 四则运算
 */
public class CalculateResult {
    private static final Logger logger = LoggerFactory.getLogger(CalculateResult.class);

    public static void main(String[] args) {
        String calculateReslut = getCalculateReslut("2,8,12,4", "$1+($2+$3)/$2");
        logger.info("{}", calculateReslut);
    }

    public static String getCalculateReslut(String valueString, String ruleString) {

        String result = "";
        try {
            String rexgex = "[(\\+)(\\-)(\\*)(\\/)(\\()(\\))(|)(\\&)(!)(>)(<)(=)]";

            String[] obj = ruleString.split(rexgex);
            String[] values = valueString.split(",");

            // 运算符
            List<String> symbol = new ArrayList<>();
            char[] objs = ruleString.toCharArray();
            for (int index = 0; index < objs.length; index++) {
                if ("+-*/()|&!><=".contains(String.valueOf(objs[index]))) {
                    symbol.add(String.valueOf(objs[index]));
                }
            }

            for (int index = 0; index < obj.length; index++) {
                // 替换$对象为数值
                if (obj[index].contains("$")) {
                    int i = Integer.valueOf(obj[index].replace("$", ""));
                    result += values[i - 1];
                } else {
                    result += obj[index];
                }
                // 拼接数值和运算符为四则表达式
                if (index < symbol.size()) {
                    result += symbol.get(index);
                }
            }

            // 获取js引擎实例
            ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("JavaScript");
            // 通过JS计算表达式
            result = scriptEngine.eval(result).toString();
            if (isNumeric(result)) {
                result = scriptEngine.eval("(" + result + ").toFixed(2)").toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
            result = "0";
        }
        return result;
    }

    /**
     * 判断是否字符串是否是数字
     *
     * @param str
     * @return
     */
    public static Boolean isNumeric(String str) {
        String reg = "^-?\\d+(\\.\\d+)?$";
        Pattern pattern = Pattern.compile(reg);
        if (StringUtils.hasLength(str)) {
            Matcher matcher = pattern.matcher(str);
            return matcher.matches();
        } else {
            return false;
        }

    }
}
